﻿using AloneLibrary.GameObjects;
using AloneLibrary.Services.Camera;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XNAnimation;
using XNAnimation.Controllers;
using XNAnimation.Effects;

namespace Alone.GameObjects
{
	public enum PlayerStance
	{
		Standing = 0,
		WalkingForward,
		WalkingBackward,
		Aiming,
		Shooting
	};

	public class BasePlayer : DynamicGameObject
	{
		protected int hp = 200;
		protected float rotationSpeed = 1f / 60f;
		protected bool move;
		protected PlayerStance currentStance, nextStance;
        public BoundingFrustum viewFrustum;

		/// <summary>
		/// Gets or sets the hp.
		/// </summary>
		/// <value>The hp.</value>
		public int Hp
		{
			get { return hp; }
			set { hp = value; }
		}

        /// <summary>
        /// Gets or sets the current stance.
        /// </summary>
        /// <value>The current stance.</value>
		public PlayerStance CurrentStance
		{
			get { return this.currentStance; }
			set { this.currentStance = value; }
		}

        /// <summary>
        /// Gets or sets the next stance.
        /// </summary>
        /// <value>The next stance.</value>
		public PlayerStance NextStance
		{
			get { return this.nextStance; }
			set { this.nextStance = value; }
		}

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="BasePlayer"/> is move.
        /// </summary>
        /// <value><c>true</c> if move; otherwise, <c>false</c>.</value>
        public bool Move {
            get { return move; }
            set { move = value; }
        }

        /// <summary>
        /// Gets or sets the rotation speed.
        /// </summary>
        /// <value>The rotation speed.</value>
        public float RotationSpeed {
            get { return rotationSpeed; }
            set { rotationSpeed = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="BasePlayer"/> class.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="animationController">The animation controller.</param>
        /// <param name="effect">The effect.</param>
        /// <param name="position">The position.</param>
        /// <param name="rotation">The rotation.</param>
        /// <param name="scale">The scale.</param>
        /// <param name="velocity">The velocity.</param>
		public BasePlayer(SkinnedModel model, AnimationController animationController, Effect effect, Vector3 position, Vector2 rotation, float scale, Vector3 velocity)
			: base(model, animationController, effect, position, rotation, scale, velocity)
		{
            this.viewFrustum = new BoundingFrustum(Matrix.Identity);
			this.ForwardSpeed = 10f;
		}

		/// <summary>
		/// Draws the specified game time.
		/// </summary>
		/// <param name="gameTime">The game time.</param>
		/// <param name="camera">The camera.</param>
		public override void Draw(GameTime gameTime, ICameraHandler camera)
		{
			Matrix[] transforms = new Matrix[skinnedModel.Model.Bones.Count];
			skinnedModel.Model.CopyAbsoluteBoneTransformsTo(transforms);

			world = Matrix.CreateScale(Scale) * 
                Matrix.CreateRotationY(Rotation.Y) * 
                Matrix.CreateTranslation(Position);

			foreach (ModelMesh modelMesh in skinnedModel.Model.Meshes)
			{
				foreach (ModelMeshPart meshPart in modelMesh.MeshParts)
				{
                    SkinnedModelBasicEffect basicEffect = (SkinnedModelBasicEffect)meshPart.Effect;
                    basicEffect.World = world;
                    basicEffect.Bones = this.animationController.SkinnedBoneTransforms;
                    basicEffect.View = camera.View;
                    basicEffect.Projection = camera.Projection;

                    // OPTIONAL - Configure material
                    basicEffect.Material.DiffuseColor = new Vector3(0.8f);
                    basicEffect.Material.SpecularColor = new Vector3(0.3f);
                    basicEffect.Material.SpecularPower = 8;

                    basicEffect.NormalMapEnabled = false;
                    basicEffect.SpecularMapEnabled = false;

                    // OPTIONAL - Configure lights
                    basicEffect.LightEnabled = true;
                    basicEffect.AmbientLightColor = new Vector3(0.2f);
                    basicEffect.EnabledLights = EnabledLights.Two;
                    basicEffect.PointLights[0].Color = Vector3.One;
                    basicEffect.PointLights[0].Position = new Vector3(-8, 4, -2);
                    basicEffect.PointLights[1].Color = Vector3.One;
                    basicEffect.PointLights[1].Position = new Vector3(-8, 4, -2);

				}
				modelMesh.Draw();
			}
		}
	}
}
